﻿using System;
using GraphDrawing.Graph.Model;

namespace GraphDrawing.Concrete
{
    public class InputSlotStrategy : ISlotStrategy
    {
        readonly int index;
        readonly IBlockLogic logicModel;

        public InputSlotStrategy(int inputIndex, IBlockLogic logicModel)
        {
            index = inputIndex;
            this.logicModel = logicModel;
        }

        public bool CanAcceptFromSameBlock
        {
            get { return false; }
        }

        public bool CanAccept(ISlotStrategy other)
        {
            var o = other as OutputSlotStrategy;
            return o != null && logicModel.CanAccept(index, o.OutputType);
        }

        public void Accept(ISlotStrategy other)
        {
            var o = other as OutputSlotStrategy;
            logicModel.Connect(index, o.GetValue());
        }
    }

    public class OutputSlotStrategy : ISlotStrategy
    {
        readonly int index;
        readonly IBlockLogic logicModel;

        public Type OutputType
        {
            get { return logicModel.InputType; }
        }

        public OutputSlotStrategy(int outputIndex, IBlockLogic logicModel)
        {
            index = outputIndex;
            this.logicModel = logicModel;
        }

        public bool CanAcceptFromSameBlock
        {
            get { return false; }
        }

        public bool CanAccept(ISlotStrategy other)
        {
            var o = other as InputSlotStrategy;
            return o != null && o.CanAccept(this);
        }

        public void Accept(ISlotStrategy other)
        {
            other.Accept(this);
        }

        public object GetValue()
        {
            return logicModel.Provide(index);
        }
    }
}